package com.xiaoyudeguang.mapper;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.ibatis.session.ResultHandler;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * @author 赵光
 */
public abstract class BaseMapperImpl<W extends Wrapper<T>, T> {

    protected BaseMapper<T> baseMapper;

    protected W wrapper;

    public BaseMapperImpl(W wrapper, BaseMapper<T> baseMapper) {
        this.wrapper = wrapper;
        this.baseMapper = baseMapper;
    }

    public void setMapper(BaseMapper<T> baseMapper) {
        this.baseMapper = baseMapper;
    }

    /**
     * 根据 ID 查询
     *
     * @param id 主键ID
     */
    public T selectById(Serializable id) {
        return getMapper().selectById(id);
    }

    /**
     * 查询（根据ID 批量查询）
     *
     * @param idList 主键ID列表(不能为 null 以及 empty)
     */
    public List<T> selectBatchIds(Collection<? extends Serializable> idList) {
        return getMapper().selectBatchIds(idList);
    }

    /**
     * 查询（根据ID 批量查询）
     *
     * @param idList        idList 主键ID列表(不能为 null 以及 empty)
     * @param resultHandler resultHandler 结果处理器 {@link ResultHandler}
     * @since 3.5.4
     */
    public void selectBatchIds(Collection<? extends Serializable> idList, ResultHandler<T> resultHandler) {
        getMapper().selectBatchIds(idList, resultHandler);
    }

    /**
     * 根据 entity 条件，查询全部记录
     *
     * @param columnMap
     * @return
     */
    public List<T> selectByMap(Map<String, Object> columnMap) {
        return getMapper().selectList((Wrappers.<T>query().allEq(columnMap)));
    }

    /**
     * 查询（根据 columnMap 条件）
     *
     * @param columnMap     表字段 map 对象
     * @param resultHandler resultHandler 结果处理器 {@link ResultHandler}
     * @since 3.5.4
     */
    public void selectByMap(Map<String, Object> columnMap, ResultHandler<T> resultHandler) {
        getMapper().selectList(Wrappers.<T>query().allEq(columnMap), resultHandler);
    }

    /**
     * 根据 entity 条件，查询一条记录
     * <p>查询一条记录，例如 qw.last("limit 1") 限制取一条记录, 注意：多条数据会报异常</p>
     */
    public T selectOne() {
        return getMapper().selectOne(wrapper, true);
    }

    /**
     * 根据 entity 条件，查询一条记录，现在会根据{@code throwEx}参数判断是否抛出异常，如果为false就直接返回一条数据
     * <p>查询一条记录，例如 qw.last("limit 1") 限制取一条记录, 注意：多条数据会报异常</p>
     *
     * @param throwEx boolean 参数，为true如果存在多个结果直接抛出异常
     */
    public T selectOne(boolean throwEx) {
        return getMapper().selectOne(wrapper, throwEx);
    }

    /**
     * 根据 Wrapper 条件，判断是否存在记录
     *
     * @return 是否存在记录
     */
    public boolean exists() {
        Long count = getMapper().selectCount(wrapper);
        return null != count && count > 0;
    }

    /**
     * 根据 Wrapper 条件，查询总记录数
     */
    public Long selectCount() {
        return getMapper().selectCount(wrapper);
    }

    /**
     * 根据 entity 条件，查询全部记录
     */
    public List<T> selectList() {
        return getMapper().selectList(wrapper);
    }

    /**
     * 根据 entity 条件，查询全部记录
     *
     * @param resultHandler 结果处理器 {@link ResultHandler}
     * @since 3.5.4
     */

    public void selectList(ResultHandler<T> resultHandler) {
        getMapper().selectList(wrapper, resultHandler);
    }

    /**
     * 根据 entity 条件，查询全部记录（并翻页）
     *
     * @param page 分页查询条件
     * @since 3.5.3.2
     */
    public List<T> selectList(IPage<T> page) {
        return getMapper().selectList(page, wrapper);
    }

    /**
     * 根据 entity 条件，查询全部记录（并翻页）
     *
     * @param page          分页查询条件
     * @param resultHandler 结果处理器 {@link ResultHandler}
     * @since 3.5.4
     */
    public void selectList(IPage<T> page, ResultHandler<T> resultHandler) {
        getMapper().selectList(page, wrapper, resultHandler);
    }

    /**
     * 根据 Wrapper 条件，查询全部记录
     */
    public List<Map<String, Object>> selectMaps() {
        return getMapper().selectMaps(wrapper);
    }

    /**
     * 根据 Wrapper 条件，查询全部记录
     *
     * @param resultHandler 结果处理器 {@link ResultHandler}
     * @since 3.5.4
     */

    public void selectMaps(ResultHandler<Map<String, Object>> resultHandler) {
        getMapper().selectMaps(wrapper, resultHandler);
    }

    /**
     * 根据 Wrapper 条件，查询全部记录（并翻页）
     *
     * @param page 分页查询条件
     * @since 3.5.3.2
     */
    public List<Map<String, Object>> selectMaps(IPage<? extends Map<String, Object>> page) {
        return getMapper().selectMaps(page, wrapper);
    }

    /**
     * 根据 Wrapper 条件，查询全部记录（并翻页）
     *
     * @param page          分页查询条件
     * @param resultHandler 结果处理器 {@link ResultHandler}
     * @since 3.5.4
     */
    public void selectMaps(IPage<? extends Map<String, Object>> page, ResultHandler<Map<String, Object>> resultHandler) {
        getMapper().selectMaps(page, wrapper, resultHandler);
    }

    /**
     * 根据 Wrapper 条件，查询全部记录
     * <p>注意： 只返回第一个字段的值</p>
     */
    public <E> List<E> selectObjs() {
        return getMapper().selectObjs(wrapper);
    }

    /**
     * 根据 Wrapper 条件，查询全部记录
     * <p>注意： 只返回第一个字段的值</p>
     *
     * @param resultHandler 结果处理器 {@link ResultHandler}
     * @since 3.5.4
     */
    public <E> void selectObjs(ResultHandler<E> resultHandler) {
        getMapper().selectObjs(wrapper, resultHandler);
    }

    /**
     * 根据 entity 条件，查询全部记录（并翻页）
     *
     * @param page 分页查询条件
     */
    public <P extends IPage<T>> P selectPage(P page) {
        page.setRecords(selectList(page));
        return page;
    }

    /**
     * 根据 Wrapper 条件，查询全部记录（并翻页）
     *
     * @param page 分页查询条件
     */
    public <P extends IPage<Map<String, Object>>> P selectMapsPage(P page) {
        page.setRecords(selectMaps(page));
        return page;
    }

    public abstract BaseMapper<T> getMapper();

    public Wrapper<T> getWrapper() {
        return wrapper;
    }
}
